package com.gdpu.service.impl;

import com.gdpu.api.CommonPage;
import com.gdpu.common.ApiException;
import com.gdpu.config.RedisConfig;
import com.gdpu.dao.ImsPurchaseOrderDao;
import com.gdpu.dao.PmsStockDao;
import com.gdpu.dto.ImsPurchaseOrderDto;
import com.gdpu.mapper.ImsPurchaseOrderMapper;
import com.gdpu.mapper.PmsGoodsMapper;
import com.gdpu.mapper.PmsStockMapper;
import com.gdpu.model.*;
import com.gdpu.serivce.RedisService;
import com.gdpu.service.ImsPurchaseOrderService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.swagger.annotations.ApiOperation;
import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Author:weiming
 * @Date:2021/5/27
 */
@Service
public class ImsPurchaseOrderServiceImpl implements ImsPurchaseOrderService {

    static Logger logger  =  Logger.getLogger(ImsPurchaseOrderServiceImpl.class);

    @Autowired
    private  ImsPurchaseOrderMapper imsPurchaseOrderMapper;
    @Autowired
    private ImsPurchaseOrderDao imsPurchaseOrderDao;
    @Autowired
    private PmsGoodsMapper pmsGoodsMapper;
    @Autowired
    private RedisConfig redisConfig;
    @Autowired
    private RedisService redisService;
    @Autowired
    private PmsStockMapper pmsStockMapper;
    @Autowired
    private PmsStockDao pmsStockDao;

    @Override
    @ApiOperation("分页查询进货订单")
    public CommonPage list(Integer pageNum, Integer pageSize) {
        Page page = PageHelper.startPage(pageNum,pageSize);
        ImsPurchaseOrderExample example = new ImsPurchaseOrderExample();
        List<ImsPurchaseOrder> list = imsPurchaseOrderMapper.selectByExample(example);
        return CommonPage.restPage(list, page);
    }


    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class)
    public int add(ImsPurchaseOrder imsPurchaseOrder) {
        Integer goodId = imsPurchaseOrder.getGoodId();
        PmsGoods pmsGoods = pmsGoodsMapper.selectByPrimaryKey(goodId);
        if (pmsGoods == null){
            throw new ApiException("商品不存在");
        }
        imsPurchaseOrder.setOrderSn(gengerateOrderSn());
        imsPurchaseOrder.setId(null);
        imsPurchaseOrder.setGoodName(pmsGoods.getGoodName());
        imsPurchaseOrder.setCreateTime(new Date());
        BigDecimal totalPrice = imsPurchaseOrder.getGoodInPrice().multiply(new BigDecimal(imsPurchaseOrder.getQuantity()));
        imsPurchaseOrder.setTotalPrice(totalPrice);
        imsPurchaseOrder.setGoodInPrice(imsPurchaseOrder.getGoodInPrice());
        int count = imsPurchaseOrderMapper.insert(imsPurchaseOrder);
        // 更新商品成本价 （当前进货总价 + 当前成本价*库存数量）/ （当前数量+进货数量）
        Integer oldGoodStock = pmsGoods.getGoodStock();

        pmsGoods.setGoodStock(pmsGoods.getGoodStock()+imsPurchaseOrder.getQuantity());
        // 总成本
        BigDecimal totalCost = totalPrice.
                add(pmsGoods.getCost().multiply(new BigDecimal(oldGoodStock)));
        // 总库存
        BigDecimal totalStock = new BigDecimal(pmsGoods.getGoodStock());
        BigDecimal avgCost = totalCost.divide(totalStock);
        pmsGoods.setCost(avgCost);
        pmsGoodsMapper.updateByPrimaryKeySelective(pmsGoods);
        return count;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addBatch(List<ImsPurchaseOrderDto> imsPurchaseOrders) {

        String oderSn = gengerateOrderSn();
        Date date = new Date();
        List<ImsPurchaseOrder> list = new ArrayList<>();
        imsPurchaseOrders.stream().forEach(e -> {
            ImsPurchaseOrder imsPurchaseOrder = new ImsPurchaseOrder();
            PmsGoods pmsGoods = pmsGoodsMapper.selectByPrimaryKey(e.getGoodId());
            if (pmsGoods == null) {
                throw new ApiException("商品不存在");
            }
            if (e.getQuantity() < 1){
                throw new ApiException("进货数量至少一件");
            }
            BeanUtils.copyProperties(e, imsPurchaseOrder);
            imsPurchaseOrder.setId(null);
            imsPurchaseOrder.setOrderSn(oderSn);
            imsPurchaseOrder.setGoodName(pmsGoods.getGoodName());
            // 总进价
            BigDecimal totalPrice = e.getGoodInPrice().multiply(new BigDecimal(e.getQuantity()));
            imsPurchaseOrder.setTotalPrice(totalPrice);
            imsPurchaseOrder.setCreateTime(date);
            Integer oldGoodStock = pmsGoods.getGoodStock();
            Integer newGoodStock = pmsGoods.getGoodStock() + e.getQuantity();
            pmsGoods.setGoodStock(newGoodStock);
            if (oldGoodStock == 0){
                pmsGoods.setCost(imsPurchaseOrder.getGoodInPrice());
            }else{
                // 总成本
                BigDecimal totalCost = totalPrice.
                        add(pmsGoods.getCost().multiply(new BigDecimal(oldGoodStock)));
                // 总库存
                BigDecimal avgCost = totalCost.divide(new BigDecimal(newGoodStock),2,BigDecimal.ROUND_CEILING);
                pmsGoods.setCost(avgCost);
            }

            pmsGoodsMapper.updateByPrimaryKeySelective(pmsGoods);
            list.add(imsPurchaseOrder);
        });
        // 商品库存表

        if (insertStock(imsPurchaseOrders) == 0){
            logger.info("库存数据库插入/更新失败");
            throw new ApiException("进货失败");
        }

        int count = imsPurchaseOrderDao.addList(list);
        return count;
    }

    private int insertStock(List<ImsPurchaseOrderDto> imsPurchaseOrders) {
        int count = 0;
        for (ImsPurchaseOrderDto imsPurchaseOrder : imsPurchaseOrders) {
            Integer goodId = imsPurchaseOrder.getGoodId();
            PmsStockExample example = new PmsStockExample();
            example.createCriteria().andGoodIdEqualTo(goodId);
            List<PmsStock> pmsStocks = pmsStockMapper.selectByExample(example);
            Integer inQuantity = imsPurchaseOrder.getQuantity();
            // 不存在存在插入
            if (pmsStocks.isEmpty()){
                PmsStock pmsStock = new PmsStock();
                pmsStock.setQuantity(inQuantity);
                pmsStock.setGoodId(imsPurchaseOrder.getGoodId());
                pmsStock.setCreateTime(new Date());
                count = pmsStockMapper.insert(pmsStock);
            }else{
                // 更新
                PmsStock pmsStock = pmsStocks.get(0);
                Integer oldQuantity = pmsStock.getQuantity();
                pmsStock.setQuantity(oldQuantity+inQuantity);
                count = pmsStockMapper.updateByPrimaryKeySelective(pmsStock);
            }

        }
        return count;
    }


    /**
     * 订单编号生成
     * @return 订单编号
     */
    private String gengerateOrderSn(){
        StringBuilder stringBuilder = new StringBuilder();
        String prefix = "GH";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String dateString = sdf.format(new Date());
        Date date = new Date();
        //TODO 自增redisId
         redisService.incr("ims_order_id:"+dateString, 1);
         redisService.expire("ims_order_id:"+dateString,3600*24);
        Integer ims_order_id = (Integer) redisService.get("ims_order_id:"+dateString);
        stringBuilder.append(prefix)
                .append(dateString)
                .append(String.format("%03d", ims_order_id));
        return stringBuilder.toString();
    }
}
